/*
 * @Author: Snow
 * @Date: 2021-09-05 22:33:27
 * @Description: 纹理简单测试
 */
import { Render } from "./Render";
import { Webgl2DBase } from "./Webgl2DBase";

export class Webgl2DTextureSimple extends Webgl2DBase{

    protected texImage:HTMLImageElement;

    protected textrue:WebGLTexture;

    public aTexCoordLoc:number;

    public aPosColorLoc:number;

    public uImageLoc:WebGLUniformLocation;

    public uSizeLoc:WebGLUniformLocation;

    public override initUITools():void{
        //super.initUITools();
        this.createSlider("red",{value: 1, slide: this.onUpateSlide(this,"red"), min: 0, max: 1, step: 0.01, precision: 2})
        this.createSlider("green",{value: 0, slide: this.onUpateSlide(this,"green"), min: 0, max: 1, step: 0.01, precision: 2})
        this.createSlider("blue",{value: 0, slide: this.onUpateSlide(this,"blue"), min: 0, max: 1, step: 0.01, precision: 2})
        this.createSlider("alpha",{value: 1, slide: this.onUpateSlide(this,"alpha"), min: 0, max: 1, step: 0.01, precision: 2})
        this.uiParam = {red:1,green:0,blue:1,alpha:1};
        this.loadImage(null);
    }

    public override initGLSL():void{
        this.vsSource = `
            attribute vec2 aPosition;
            attribute vec2 aTexCoord;
            attribute vec4 aPosColor;

            
            uniform vec2 uResolution;
            
            uniform mat4 uModelViewMatrix;
            uniform mat4 uProjectionMatrix;
            uniform mat4 uViewMatrix;

            varying mediump vec2 vTexCoord;
            varying mediump vec4 vPosColor;

            void main() {
                // 从像素坐标转换到 0.0 到 1.0
            vec2 zeroToOne = aPosition / uResolution;
        
            // 再把 0->1 转换 0->2
            vec2 zeroToTwo = zeroToOne * 2.0;
        
            // 把 0->2 转换到 -1->+1 (裁剪空间)
            vec2 clipSpace = zeroToTwo - 1.0;
        
            gl_Position = vec4(clipSpace * vec2(1,-1), 0, 1);
            vTexCoord = aTexCoord;
            vPosColor = aPosColor;
            }
        `;
        
        this.fsSource = `
            
            // 纹理
            uniform sampler2D uImage;

            precision mediump float;

            //纹理size
            uniform vec2 uSize;

            
            varying mediump vec2 vTexCoord;
            varying mediump vec4 vPosColor;

            void main() {
                //纹理像素
                vec4 color = texture2D(uImage, vTexCoord);
                //gl_FragColor = (color + vPosColor) / 2.0;
                gl_FragColor = color;
                //红 蓝颜色对调
                //gl_FragColor = vec4(color.b,color.g,color.r,color.a);
                
                //变灰
                //float rgb = color.r + color.g + color.b;
                //rgb = rgb / 3.0;
                //gl_FragColor = vec4(rgb,rgb,rgb,color.a);

                // 计算1像素对应的纹理坐标
                //vec2 onePixel = vec2(1.0, 1.0) / uSize;
                // 对左中右像素求均值
                // gl_FragColor = (
                //     texture2D(uImage, vTexCoord) +
                //     texture2D(uImage, vTexCoord + vec2(onePixel.x, 0.0)) +
                //     texture2D(uImage, vTexCoord + vec2(-onePixel.x, 0.0))) / 3.0;
            }
            `;

                
    }

    protected loadImage(url:string):void{
        const gl = Render.GL;
        let image = new Image();
        image.src = "./texture.png";  // MUST BE SAME DOMAIN!!!
        image.onload = () => {
           this.texImage = image;
           this.textrue = gl.createTexture();
        };
    }

    public override initProgramInfo():any{
        this.aPositionLoc = this.gl.getAttribLocation(this.shaderProgram,"aPosition");
        
        this.aPosColorLoc = this.gl.getAttribLocation(this.shaderProgram,"aPosColor");

        this.aTexCoordLoc = this.gl.getAttribLocation(this.shaderProgram,"aTexCoord");
        
        this.uResolutionLoc = this.gl.getUniformLocation(this.shaderProgram,"uResolution");

        this.uImageLoc = this.gl.getUniformLocation(this.shaderProgram,"uImage");
        
        this.uSizeLoc = this.gl.getUniformLocation(this.shaderProgram,"uSize");
        return null;
    }

    public override draw():void{
        const gl = this.gl;
        gl.viewport(0,0,gl.canvas.width,gl.canvas.height);
        gl.clearColor(1,1,1,1);
        gl.clearDepth(1.0);
		gl.enable(gl.DEPTH_TEST);
		gl.depthFunc(gl.LEQUAL);
		gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        const pos:number[] = [
            100,100,
            200,100,
            200,200,
            100,200,
        ];

        const posBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER,posBuffer);
        gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(pos),gl.STATIC_DRAW);
        gl.enableVertexAttribArray(this.aPositionLoc);
        {
            gl.vertexAttribPointer(this.aPositionLoc,2,gl.FLOAT,false,0,0);
        }

        // const posColor:number[] = [
        //     Math.random(),0,0,1,
        //     0,Math.random(),0,1,
        //     0,0,Math.random(),1,
        //     Math.random(),Math.random(),Math.random(),1,
        // ];

        // const posColorBuffer = gl.createBuffer();
        // gl.bindBuffer(gl.ARRAY_BUFFER,posColorBuffer);
        // gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(posColor),gl.STATIC_DRAW);
        // gl.enableVertexAttribArray(this.aPosColorLoc);
        // {
        //     gl.vertexAttribPointer(this.aPosColorLoc,4,gl.FLOAT,false,0,0);
        // }

        //纹理坐标
        const texPos:number[] = [
            0.0,0.0,
            1.0,0.0,
            1.0,1.0,
            0.0,1.0
        ];

        const texBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER,texBuffer);
        gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(texPos),gl.STATIC_DRAW);
        gl.enableVertexAttribArray(this.aTexCoordLoc);
        {
            gl.vertexAttribPointer(this.aTexCoordLoc,2,gl.FLOAT,false,0,0);
        }

        // 创建纹理
        if(this.textrue && this.texImage){
            //this.textrue = gl.createTexture();
            gl.bindTexture(gl.TEXTURE_2D, this.textrue);
            
            // 设置参数，让我们可以绘制任何尺寸的图像
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    
            // 将图像上传到纹理
            //if(this.texImage)
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.texImage);
        }
        if(this.textrue){
            //使用纹理
            gl.uniform1i(this.uImageLoc, 0);
            gl.activeTexture(gl.TEXTURE0);
            gl.bindTexture(gl.TEXTURE_2D,this.textrue);
        }

        //顶点
        const indexs = [
            0,1,2,2,3,0
        ];

        const indexsBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexsBuffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,new Uint16Array(indexs),gl.STATIC_DRAW);


        gl.useProgram(this.shaderProgram);

        const resolution:number[] = [
            gl.canvas.width,gl.canvas.height,
        ]

        gl.uniform2fv(this.uResolutionLoc,new Float32Array(resolution));
        
        let red = this.uiParam["red"];
        let green = this.uiParam["green"];
        let blue = this.uiParam["blue"];
        let alpha = this.uiParam["alpha"];

        gl.uniform4fv(this.uColorLoc,new Float32Array([red,green,blue,alpha]));

        if(this.texImage)
        gl.uniform2f(this.uSizeLoc,this.texImage.width,this.texImage.height);
        

        //gl.drawArrays(gl.TRIANGLES,0,6);
        gl.drawElements(gl.TRIANGLES,6,gl.UNSIGNED_SHORT,0);
    }
}